import 'package:flutter/material.dart';
import 'package:ribo_base_core/base_models/base_chart_axis.dart';
import 'package:ribo_base_core/base_models/base_chart_formatter.dart';
import 'package:ribo_base_core/base_models/base_chart_model.dart';
import 'package:ribo_base_core/base_models/base_chart_two_sides_bar_model.dart';
import 'package:ribo_base_core/base_styles/base_chart_style.dart';
import 'base_chart.dart';

class BaseChartTwoSidesBar extends StatefulWidget {
  BaseChartTwoSidesBar({Key key, @required this.model}) : super(key: key);
  final BaseChartTwoSidesBarModel model;

  @override
  _BaseChartTwoSidesBarState createState() => _BaseChartTwoSidesBarState();
}

class _BaseChartTwoSidesBarState extends State<BaseChartTwoSidesBar> {
  Map<String, dynamic> _option;

  @override
  Widget build(BuildContext context) {
    _handleModel();

    return BaseChart(
        model:
            BaseChartModel(style: widget.model?.style, option: this._option));
  }

  void _handleModel() {
    List<BaseChartTwoSidesBarData> data = widget.model?.data;
    List<String> legends = data.map((item) => item.name).toList();
    List<String> yAxisData = data[0].data.map((item) => item.name).toList();
    BaseChartAxis baseChartAxis = BaseChartAxis();

    List<double> values1 = data[0].data.map((e) => e.value.abs()).toList();
    List<double> values2 = data[1].data.map((e) => e.value.abs()).toList();
    values1.sort();
    values2.sort();
    double maxValue1 = values1[values1.length - 1];
    double maxValue2 = values2[values2.length - 1];
    double maxValue = maxValue1 > maxValue2 ? maxValue1 : maxValue2;

    this._option = {
      'legend': {
        ...BaseChartLegendStyle().toJson(),
        'data': legends,
        'bottom': '0%',
        ...widget.model?.style?.legend?.toJson() ?? {}
      },
      'xAxis': <Map<String, dynamic>>[
        {
          ...(widget.model?.axis ?? baseChartAxis).toJson()['xAxis'],
          'type': 'value',
          'min': -maxValue,
          'max': maxValue,
          'axisLabel': {
            ...(widget.model?.axis ?? baseChartAxis).toJson()['xAxis']
                ['axisLabel'],
            'formatter': widget.model?.xAxisLabelFormatter?.toJson()
          },
        }
      ],
      'yAxis': <Map<String, dynamic>>[
        {
          ...(widget.model?.axis ?? baseChartAxis).toJson()['yAxis'],
          'type': 'category',
          'data': yAxisData,
          'axisLabel': {
            ...(widget.model?.axis ?? baseChartAxis).toJson()['yAxis']
                ['axisLabel'],
            'margin': 30,
            'formatter': widget.model?.yAxisLabelFormatter?.toJson()
          },
        }
      ],
      'tooltip': {
        'trigger': 'axis',
        "triggerOn": "click",
        "confine": true,
        'axisPointer': {'type': 'shadow'},
        'formatter': widget.model?.tooltipFormatter?.toJson() ??
            BaseChartFormatter.fromFunction(
                "function(e){const item1=e[0];const item2=e[1];const axisValue=item1.axisValue;const str1=item1.marker+item1.seriesName+': '+Math.abs(item1.value);const str2=item2.marker+item2.seriesName+': '+Math.abs(item2.value);return axisValue+'</br></br>'+str1+'</br>'+str2}")
      },
      'series': data
          .asMap()
          .keys
          .map((i) => {
                'name': data[i].name,
                'type': 'bar',
                'stack': 'stack',
                "barWidth": '65%',
                'data': data[i]
                    .data
                    .map((item) => item.value * ((i % 2 == 0) ? -1 : 1))
                    .toList(),
                'itemStyle': data[i]?.itemStyle?.toJson() ?? {},
                'label': {
                  "show": true,
                  "position": (i % 2 == 0) ? 'left' : 'right',
                  "fontSize": 8,
                  'formatter': widget.model?.labelFormatter?.toJson() ??
                      BaseChartFormatter.fromFunction(
                              'function(e){return Math.abs(e.value);}')
                          .toJson()
                }
              })
          .toList(),
    };
  }
}
